
#include "qyTimerWin32.h"

//-----------------------------------------------------------------------
qyTimerWin32::qyTimerWin32()
{

}

//-----------------------------------------------------------------------
qyTimerWin32::~qyTimerWin32()
{

}

//-----------------------------------------------------------------------
void qyTimerWin32::Reset()
{
	DWORD procMask, sysMask;
	GetProcessAffinityMask( GetCurrentProcess(), &procMask, &sysMask );

	if ( procMask == 0 )
		procMask = 1;

	if ( m_timerMask == 0 )
	{
		m_timerMask = 1;
		while ( ( m_timerMask & procMask ) == 0 )
		{
			m_timerMask <<= 1;
		}
	}

	HANDLE thread = GetCurrentThread();

	DWORD oldMask = SetThreadAffinityMask( thread, (DWORD_PTR)m_timerMask );

	QueryPerformanceFrequency( &m_Frequency );

	QueryPerformanceFrequency( &m_startTime );
	m_startTick = GetTickCount();

	SetThreadAffinityMask( thread, oldMask );

	m_lastTime = 0;
	m_zeroClock = clock();
}

//-----------------------------------------------------------------------
unsigned long qyTimerWin32::GetMilliseconds()
{
	LARGE_INTEGER curTime;
	HANDLE thread = GetCurrentThread();

	DWORD oldMask = SetThreadAffinityMask( thread, (DWORD_PTR)m_timerMask );

	QueryPerformanceCounter( &curTime );

	SetThreadAffinityMask( thread, (DWORD_PTR)oldMask );

	LONGLONG newTime = curTime.QuadPart - m_startTime.QuadPart;

	unsigned long newTicks = (unsigned long) ( 1000 * newTime / m_Frequency.QuadPart );

	unsigned long check = GetTickCount() - m_startTick;
	signed long msecOff = (signed long)(newTicks - check);
	if ( msecOff < -100 || msecOff > 100 )
	{
		LONGLONG adjust = min( msecOff * m_Frequency.QuadPart / 1000, newTime - m_lastTime );
		m_startTime.QuadPart += adjust;
		newTime -= adjust;

		newTicks = (unsigned long) ( 1000 * newTime / m_Frequency.QuadPart );
	}
	m_lastTime = newTime;

	return newTicks;
}

//-----------------------------------------------------------------------
unsigned long qyTimerWin32::GetMicroseconds()
{
	LARGE_INTEGER curTime;
	HANDLE thread = GetCurrentThread();

	DWORD oldMask = SetThreadAffinityMask( thread, m_timerMask );

	QueryPerformanceCounter( &curTime );

	SetThreadAffinityMask( thread, oldMask );

	LONGLONG newTime = curTime.QuadPart - m_startTime.QuadPart;

	unsigned long newTicks = (unsigned long) ( 1000 * newTime / m_Frequency.QuadPart );

	unsigned long check = GetTickCount() - m_startTick;
	signed long msecOff = (signed long)( newTicks - check );
	if ( msecOff < -100 || msecOff > 100 )
	{
		LONGLONG adjust = min( msecOff * m_Frequency.QuadPart / 1000, newTime - m_lastTime );
		m_startTime.QuadPart += adjust;
		newTime -= adjust;
	}
	m_lastTime = newTime;

	unsigned long newMicro = (unsigned long)( 1000000 * newTime / m_Frequency.QuadPart );
	
	return newMicro;
}

//-----------------------------------------------------------------------
unsigned long qyTimerWin32::GetMillisecondsCPU()
{
	clock_t newClock = clock();
	return (unsigned long)( (float)( newClock - m_zeroClock ) / ( (float) CLOCKS_PER_SEC / 1000.0 ) );
}

//-----------------------------------------------------------------------
unsigned long qyTimerWin32::GetMicrosecondsCPU()
{
	clock_t newClock = clock();
	return (unsigned long)( (float)( newClock - m_zeroClock ) / ( (float) CLOCKS_PER_SEC / 1000000.0 ) );
}





